home *** CD-ROM | disk | FTP | other *** search
- #include "ic_part.h"
-
- #include <mem.h>
- #include "image_p.h"
- #include "output.h"
-
- //////////////////////////
- void cut_image_horiz(imageP image, int height, int leave_up)
- {
- if(leave_up)
- imageP(image)->ymax = height - 1;
- else
- {
- int line_size = ((imageP(image)->xmax + 1 + 7) >> 3) << N_PLANE_SH;
- memcpy(imageP(image)->data,
- imageP(image)->data + line_size * height,
- (imageP(image)->ymax + 1 - height) * line_size);
- imageP(image)->ymax -= height;
- }
- }
- //////////////////////////
- void cut_image_vert(imageP image, int width, int leave_left)
- {
- int line_bytes_old = ((image->xmax + 1 + 7) >> 3);
- if(leave_left)
- {
- int line_bytes_new = (width + 7) >> 3;
- image->xmax = width - 1;
-
- int i, s, d;
-
- for(i = s = d = 0; i <= image->ymax; i++)
- {
- for(int plane = 0; plane < N_PLANES; plane++)
- {
- for(int j = 0; j < line_bytes_new; j++)
- image->data[d++] = image->data[s + j];
- s += line_bytes_old;
- }
- }
- }
- else
- {
- int bits_left = image->xmax - width + 1;
- int i, s, d;
- int line_bytes_new = line_bytes_old - ((width + 7) >> 3);
- s = (width + 7) >> 3;
- for(i = d = 0; i <= image->ymax; i++)
- {
- for(int plane = 0; plane < N_PLANES; plane++)
- {
- for(int j = 0; j < line_bytes_new; j++)
- image->data[d++] = image->data[s + j];
- s += line_bytes_old;
- }
- }
- image->xmax = bits_left - 1;
- }
- }
- ////////////////////////////
- inline void image_cut(imageP image, imageP work, int x, int bplin, int sz)
- {
- unsigned char* dest = work->data;
- unsigned char* src = image->data + (x >> 3);
-
- memcpy(dest, src, sz); // for 4 planes
- memcpy(dest += sz, src += bplin, sz);
- memcpy(dest += sz, src += bplin, sz);
- memcpy(dest += sz, src += bplin, sz);
- }
- ////////////////////////////
- void cut_image(imageP image, rect src, rect dest)
- {
- int leave_left = 0;
- int leave_up = 0;
- int height, width;
-
- if(src.origin.X == dest.origin.X)
- {
- leave_left = 1;
- width = dest.width();
- }
- else
- width = src.width() - dest.width();
- if(src.origin.Y == dest.origin.Y)
- {
- leave_up = 1;
- height = dest.height();
- }
- else
- height = src.height() - dest.height();
-
- if(!(src.origin.Y == dest.origin.Y && src.corner.Y == dest.corner.Y))
- cut_image_horiz(image, height, leave_up);
- if(!(src.origin.X == dest.origin.X && src.corner.X == dest.corner.X))
- cut_image_vert(image, width, leave_left);
- }
- ///////////////////////////
- void put_image_correct(imageP image, rect src) // src in abs screen coord
- {
- struct viewporttype viewinfo;
- getviewsettings(&viewinfo);
-
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- rect r(viewinfo.left, viewinfo.top, viewinfo.right, viewinfo.bottom);
-
- if(r.contains(src))
- {
- putimage(src.origin.X, src.origin.Y, image, COPY_PUT);
- setviewport(viewinfo.left, viewinfo.top,
- viewinfo.right, viewinfo.bottom, 1);
- return;
- }
- if(!r.contains(src.origin) && !r.contains(src.corner) &&
- !r.contains(loc(src.origin.X, src.corner.Y)) &&
- !r.contains(loc(src.corner.X, src.corner.Y)))
- {
- setviewport(viewinfo.left, viewinfo.top,
- viewinfo.right, viewinfo.bottom, 1);
- return;
- }
- rect dest;
- dest.origin.X = r.origin.X > src.origin.X ? r.origin.X : src.origin.X;
- dest.origin.Y = r.origin.Y > src.origin.Y ? r.origin.Y : src.origin.Y;
- dest.corner.X = r.corner.X < src.corner.X ? r.corner.X : src.corner.X;
- dest.corner.Y = r.corner.Y < src.corner.Y ? r.corner.Y : src.corner.Y;
-
- cut_image(image, src, dest);
- putimage(dest.origin.X, dest.origin.Y, image, COPY_PUT);
-
- setviewport(viewinfo.left, viewinfo.top,
- viewinfo.right, viewinfo.bottom, 1);
- }
- //////////////////////////
- void cut(imageP image, rect src) // src - position of rectangle inside image
- {
- cut_image(image, rect(0, 0, image->xmax, image->ymax),
- rect(src.origin, loc(image->xmax, image->ymax)));
- src.corner.X -= src.origin.X;
- src.corner.Y -= src.origin.Y + 1;
- cut_image(image, rect(0, 0, image->xmax, image->ymax),
- rect(0, 0, src.corner.X, src.corner.Y));
- }
- ////////////////////////////
- void putimage(int x, int y, imageP image, // for 25x80 cells screen, show
- int* cells, imageP work, // only cells, which are listed
- int bplin, int mode)
- {
- if(cells == NULL)
- ::putimage(x, y, image, mode);
- else
- {
- int i = 0; // Cells counter
- rect r_out = textRect(rect(x, 0, x + image->xmax, 0));
- int r_out_L = r_out.origin.X;
- int r_out_R = r_out.corner.X;
-
- int num = 0; // Number of continuous cells.
- int s_left; // First cell in visible raw
- int raw = y / pScreenSet->cell_height;
-
- int bytes_per_cell = 1 << (pScreenSet->log2cell_width - 3);
- int reserv = -5;
- while(cells[i] != -1)
- {
- int top = cells[i] / 80;
-
- if(raw != top || cells[i] < 0) // Skip this raw
- {
- i++; continue;
- }
- int left = cells[i] - top * 80;
- if(!num) // Start in raw of cells
- s_left = left;
- if(left < r_out_R && left >= r_out_L
- && (!num || (cells[i] == reserv + 1)))
- {
- reserv = cells[i];
-
- if(!((y + 1) % pScreenSet->cell_height))
- cells[i] = -2;
- num++;
- }
- else
- {
- if(num) // end of visible raw
- {
- int r_left = screenXL(s_left);
- int sz = bytes_per_cell * num;
- work->xmax = (num << pScreenSet->log2cell_width) - 1;
- image_cut(image, work, r_left - x, bplin, sz);
- ::putimage(r_left, y, work, mode);
- num = 0;
- i--;
- }
- }
- i++;
- }
- if(cells[i] == -1 && num)
- {
- int r_left = screenXL(s_left);
- int sz = bytes_per_cell * num;
- work->xmax = (num << pScreenSet->log2cell_width) - 1;
- image_cut(image, work, r_left - x, bplin, sz);
- ::putimage(r_left, y, work, mode);
- }
- }
- }
-